from manimlib import *


class SingleCharText(Text):
    CONFIG = {
        'font': 'Consolas',
        'monospace': True,
    }

    def __init__(self, text: str, **kwargs):
        assert len(text) == 1
        super().__init__(text, **kwargs)
        if self.monospace:
            self.init_monospaced_bb(**kwargs)
            self.disable_bb_functions()
        

        # structure:
        # 1. process single char svgs
        # 2. __init__ object
        # 3. init bounding box
        # 4. init color slant

    def disable_bb_functions(self):
        self.refresh_bounding_box = self.refresh_bounding_box2
        self.compute_bounding_box = None
        self.get_bounding_box = self.get_bounding_box2

    def init_monospaced_bb(self, **kwargs):
        all_points = Text('w', font=self.font, **kwargs).get_all_points()
        mins = all_points.min(0)
        maxs = all_points.max(0)
        mids = (mins + maxs) / 2
        self.needs_new_bounding_box = False
        self.data["bounding_box"] = np.array([mins, mids, maxs])

    def refresh_bounding_box2(self, recurse_down=False, recurse_up=True):
        pass

    def get_bounding_box2(self):
        return self.data["bounding_box"]

    def apply_points_function(self, func, about_point=None, about_edge=ORIGIN, works_on_bounding_box=True):
        return super().apply_points_function(func, 
            about_point=about_point, about_edge=about_edge, works_on_bounding_box=works_on_bounding_box)


class TestSingleChar(Scene):
    def construct(self):
        s = SingleCharText('s').shift(DOWN)
        r = SurroundingRectangle(s, buff=0)
        r.add_updater(lambda a: a.become(SurroundingRectangle(s, buff=0)))
        # s.add_updater(lambda a: print(s.get_center()))
        self.add(s, r)
        # self.wait()
        # s.scale(2)
        # self.add(s)
        # self.wait()
        # s.shift(UP)
        # self.wait()
        # print(s.get_bounding_box())
        # self.add(s, r)
        self.wait()
        self.play(s.animate.scale(2))
        self.wait()
        self.play(s.animate.shift(UP))
        self.wait()